package com.share.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.share.common.result.ResponseResult;
import com.share.util.common.ResponseUtils;
import com.share.util.common.StringUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 登录失败处理器
 */
@Slf4j
@Component
public class CustomLoginAuthenticationFailureHandler implements AuthenticationFailureHandler {

    private final AuthenticationExceptionHandler exceptionHandler;

    public CustomLoginAuthenticationFailureHandler(AuthenticationExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        // 获取用户名
        String username = request.getParameter("username");
        // 如果表单提交的数据为空，则尝试从请求体中解析 JSON 数据
        if (!StringUtils.isEmpty(username)) {
            String requestBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
            // 使用ObjectMapper将JSON字符串转换为Map
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, String> credentials = objectMapper.readValue(requestBody, Map.class);
            if(StringUtils.isEmpty(credentials)){
                // 从Map中获取用户名和密码
                username = credentials.get("username");
            }
        }

        // 获取异常信息
        AuthenticationExceptionHandler.AuthenticationFailureInfo failureInfo =
                exceptionHandler.getFailureInfo(exception);

        // 记录认证失败日志
        exceptionHandler.logAuthenticationFailure(request, exception, username);

        // 构建响应结果
        ResponseResult<String> result = ResponseResult.fail(
                        failureInfo.getStatus().getCode(),
                        failureInfo.getMessage());

        // 返回响应
        ResponseUtils.result(response, result);
    }
}